﻿using System;
using System.Configuration;
using System.Data;
using System.Data.Common;

namespace Dorm.Helpers
{
    public class DataAccess: IDisposable
    {
        private readonly IDbConnection _connection;

        private IDbConnection Connection
        {
            get
            {
                if (_connection.State != ConnectionState.Open)
                    _connection.Open();
                return _connection;
            }
        }

        private IDbTransaction Transaction { get; set; }

        public bool HasValidTransaction { get { return Transaction != null; } }

        public DataAccess()
        {
            _connection = GetProviderFactory().CreateConnection();
            _connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
        }

        public IDataReader ExecuteReader(String query)
        {
            IDbCommand command = GetProviderFactory().CreateCommand();
            command.Connection = Connection;
            command.Transaction = Transaction;
            command.CommandText = query;
            return command.ExecuteReader();
        }
       
        public int ExecuteNonQuery(String query)
        {
            IDbCommand command = GetProviderFactory().CreateCommand();
            command.Connection = Connection;
            command.Transaction = Transaction;
            command.CommandText = query;
            return command.ExecuteNonQuery();
        }

        public object ExecuteScalar(String query)
        {
            IDbCommand command = GetProviderFactory().CreateCommand();
            command.Connection = Connection;
            command.Transaction = Transaction;
            command.CommandText = query;
            return command.ExecuteScalar();
        }

        public void BeginTransaction()
        {
            Transaction = Connection.BeginTransaction();
        }

        public void CommitTransaction()
        {
            Transaction.Commit();
        }

        public void RollbackTransaction()
        {
            Transaction.Rollback();
        }   

        private static DbProviderFactory GetProviderFactory()
        {
            string provider = ConfigurationManager.ConnectionStrings["ConnectionString"].ProviderName;

            if (provider.Trim() != "")
                return DbProviderFactories.GetFactory(provider);
            else
                throw new ConfigurationErrorsException("O Provider não foi informado.");
        }

        public void Dispose()
        {
            if (Connection.State != ConnectionState.Closed)
                Connection.Close();
            Connection.Dispose();
        }
    }
}
